package data

import (
	"context"
	"encoding/json"

	v1 "MdfServer/api/room/v1"
	"MdfServer/internal/room/biz"

	"github.com/go-redis/redis/v8"
)

// redisRoomRepo Redis实现的房间存储
type redisRoomRepo struct {
	redisClient *redis.Client // Redis客户端
}

// NewRoomRepo 创建房间数据访问实例
func NewRoomRepo(redisClient *redis.Client) biz.RoomRepo {
	return &redisRoomRepo{
		redisClient: redisClient,
	}
}

// Save 保存房间信息到Redis
func (r *redisRoomRepo) Save(ctx context.Context, room *v1.Room) error {
	key := "room:" + room.RoomId
	data, err := json.Marshal(room)
	if err != nil {
		return err
	}
	// 房间数据永不过期，由后台协程清理超时房间
	return r.redisClient.Set(ctx, key, data, 0).Err()
}

// Get 从Redis获取房间信息
func (r *redisRoomRepo) Get(ctx context.Context, roomID string) (*v1.Room, error) {
	key := "room:" + roomID
	data, err := r.redisClient.Get(ctx, key).Bytes()
	if err != nil {
		return nil, err // 房间不存在会返回redis.Nil错误
	}
	var room v1.Room
	if err := json.Unmarshal(data, &room); err != nil {
		return nil, err
	}
	return &room, nil
}

// Delete 从Redis删除房间
func (r *redisRoomRepo) Delete(ctx context.Context, roomID string) error {
	key := "room:" + roomID
	return r.redisClient.Del(ctx, key).Err()
}

// ListExpired 列出所有超时房间（创建时间 < expiredTime）
func (r *redisRoomRepo) ListExpired(ctx context.Context, expiredTime int64) ([]*v1.Room, error) {
	var expiredRooms []*v1.Room

	// 扫描所有房间键（Redis的SCAN命令）
	iter := r.redisClient.Scan(ctx, 0, "room:*", 0).Iterator()
	for iter.Next(ctx) {
		key := iter.Val()
		data, err := r.redisClient.Get(ctx, key).Bytes()
		if err != nil {
			continue // 忽略获取失败的键
		}

		var room v1.Room
		if err := json.Unmarshal(data, &room); err != nil {
			continue // 忽略解析失败的数据
		}

		// 检查是否超时
		if room.CreateTime < expiredTime {
			expiredRooms = append(expiredRooms, &room)
		}
	}

	if err := iter.Err(); err != nil {
		return nil, err
	}
	return expiredRooms, nil
}
